package com.whately.core.base.utils.http;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;

@Component
public class RestTemplateUtil {

    private static final Logger logger = LoggerFactory
            .getLogger(RestTemplateUtil.class);

    @Autowired
    private RestTemplate restTemplate;

    private final static String ASK = "?";

    private final static String AND = "&";


    /**
     * post json
     */
    public String doPostStringJson(String url, String args) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(new MediaType("application" ,"json", Charset.forName("UTF-8")));
            HttpEntity<String> entity = new HttpEntity<String>(args, headers);
            String result = restTemplate.postForObject(url, entity,
                    String.class);
            return result;
        } catch (Exception e) {
            logger.error("doPostStringJson failed!", e);
            return null;
        }
    }

    /**
     * get
     */
    public String doGet(final String uri, final Map<String, String> content) {
        String result = null;
        try {
            if (content != null) {
                StringBuilder url = new StringBuilder(uri);
                url.append(ASK);
                for (Map.Entry<String, String> entry : content.entrySet()) {
                    url.append(entry.getKey() + "=" + entry.getValue() + AND);
                }
                result = restTemplate.getForObject(url.toString().substring(0, url.length() - 1), String.class);
            } else {
                result = restTemplate.getForObject(uri, String.class);
            }
        } catch (Exception e) {
            logger.error("doGet failed!", e);
        }
        return result;
    }


    /**
     * post
     */
    public <T> T postForObject(String url, Object request, Class<T> responseType) {
        try {
            return restTemplate.postForObject(url, request,
                    responseType);
        } catch (Exception e) {
            logger.error("postForObject failed!url:"+url, e);
            return null;
        }
    }



    /**
     * post with header
     */
    public <T> T postForObject(String url, Object requestObject, Class<T> responseType,HttpHeaders headers) {
        try {
            if(headers==null){
                headers = new HttpHeaders();
            }
            HttpEntity<Object> entity = new HttpEntity<>(requestObject, headers);
            return restTemplate.postForObject(url, entity,
                    responseType);
        } catch (Exception e) {
            logger.error("postForObject with header failed!url:"+url, e);
            return null;
        }
    }

    public <T> T get(String path, Map request, Class<T> responseType) {

        logger.debug("begin to do http get. path:{}, request params:{}", path, request);

        //add accept json
        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<?> entity = new HttpEntity<>(headers);

        //url
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(path);

        //添加参数
        Map<String, ?> params = (Map<String, ?>) request;
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, ?> urlParam : params.entrySet()) {
                builder.queryParam(urlParam.getKey(), urlParam.getValue());
            }
        }
        final URI getURI = builder.build().encode().toUri();

        try {
            HttpEntity<T> response = restTemplate.exchange(getURI, HttpMethod.GET, entity, responseType);
            logger.debug("end to do http get. path:{}, request params:{}. response body: {}", path, request, response.getBody());
            return response.getBody();
        } catch (Exception e) {
            logger.error("doPostStringJson failed!url:"+path, e);
            return null;
        }
    }



    public <T> T getWithHeaderHost(String path, Map request, Class<T> responseType) {

        logger.debug("begin getWithHeaderHost. path:{}, request params:{}", path, request);

        //add accept json
        HttpHeaders headers = new HttpHeaders();
       // headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
        headers.set("Host", "hots.one.test");
        HttpEntity<?> entity = new HttpEntity<>(headers);

        //url
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(path);

        //添加参数
        if(request!=null){
            Map<String, ?> params = (Map<String, ?>) request;
            if (params != null && params.size() > 0) {
                for (Map.Entry<String, ?> urlParam : params.entrySet()) {
                    builder.queryParam(urlParam.getKey(), urlParam.getValue());
                }
            }
        }

        final URI getURI = builder.build().encode().toUri();

        try {
            HttpEntity<T> response = restTemplate.exchange(getURI, HttpMethod.GET, entity, responseType);
            logger.debug("getWithHeaderHost end. path:{}, request params:{}. response body: {}", path, request, response.getBody());
            return response.getBody();
        } catch (Exception e) {
            logger.error("getWithHeaderHost failed!url:"+path, e);
            return null;
        }
    }


    public <T> T getwithauth(String path, Map request, Class<T> responseType) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        headers.set("Authorization", "ypdkeything");
        HttpEntity<?> entity = new HttpEntity<>(headers);

        //url
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(path);
        //添加参数
        Map<String, ?> params = (Map<String, ?>) request;
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, ?> urlParam : params.entrySet()) {
                builder.queryParam(urlParam.getKey(), urlParam.getValue());
            }
        }
        final URI getURI = builder.build().encode().toUri();
        try {
            HttpEntity<T> response = restTemplate.exchange(getURI, HttpMethod.GET, entity, responseType);
            logger.debug("end to do http get. path:{}, request params:{}. response body: {}", path, request, response.getBody());
            return response.getBody();
        } catch (Exception e) {
            logger.error("doPostStringJson failed!url:" + path, e);
            throw e;
            //return null;
        }
    }
}
